import { UIOpacity, Camera } from 'cc';
import { EventTouch } from 'cc';
import { _decorator, Component, Node } from 'cc';
import { EventTypes } from '../../Init/Managers/EventTypes';
import EventManager from '../../Init/Managers/EventManager';
import { Vec3 } from 'cc';
import { BlockInputEvents } from 'cc';
import { v3 } from 'cc';
import GlobalData from '../../Init/Config/GlobalData';
import { GlobalEnum } from '../../Init/Config/GlobalEnum';
import { UITransform } from 'cc';
import { size } from 'cc';
import { Material } from 'cc';
import { Sprite } from 'cc';
import { v4 } from 'cc';
import { view } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('CircleMaskCmp')
export class CircleMaskCmp extends Component {
    uiopacity: UIOpacity = null;
    block: BlockInputEvents = null;
    mat: Material = null;

    screeSize = size();
    opacityRate = 0;
    tarOpacityRate = 0;
    // xy缩放 zw偏移
    maskParam = v4(6, 6, 0, 0);
    maskParamName = 'maskTilingOffset';
    curPos = v3();
    tarPos = v3();
    curRadius = 0;
    //
    clickCb = null;
    isAnimFinished = false;

    protected onLoad(): void {
        this.mat = this.node.getComponent(Sprite).customMaterial;
        this.uiopacity = this.node.getComponent(UIOpacity);
        this.block = this.node.getComponent(BlockInputEvents);
        this.block.enabled = false;
        this.uiopacity.opacity = 0;

        this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        EventManager.on(EventTypes.UIEvents.ShowCircleMask, this.onShowCircleMask, this);
        EventManager.on(EventTypes.UIEvents.HideCircleMask, this.onHideCircleMask, this);
        
    }

    onEnable(): void {
        this.screeSize.set(view.getVisibleSize());
        this.mat.setProperty('screenSize', v4(this.screeSize.width, this.screeSize.height, 0, 0));
        this.curRadius = (this.screeSize.width / this.maskParam.x) * 0.5;
        this.curPos.set(0, 0, 0);
        this.tarPos.set(0, 0, 0);
        //
        this.uiopacity.opacity = 0;
        this.opacityRate = 0;
        this.tarOpacityRate = 0;
        this.block.enabled = false;
        //
        this.clickCb = null;
        // 
        EventManager.emit(EventTypes.UIEvents.CircleMaskReady);
    }

    update(dt: number): void {
        // 透明动画
        const subR = this.tarOpacityRate - this.opacityRate;
        if (subR !== 0) {
            this.opacityRate += subR * 0.2;
            if (subR < 0.01) {
                this.opacityRate = this.tarOpacityRate;
            }
            this.uiopacity.opacity = this.opacityRate * 255;
        }
        // 位移动画
        if (!this.isAnimFinished) {
            tmpP3_0.set(this.tarPos).subtract(this.curPos);
            if (tmpP3_0.length() < 0.1) {
                this.isAnimFinished = true;
                this.tarPos.set(this.tarPos);
            }
            this.curPos.add(tmpP3_0.multiplyScalar(0.2));
            this.setMaskParam(this.curPos);
        }
    }

    // 设置Mask位置
    setMaskParam(pos: Vec3) {
        this.maskParam.z = - pos.x / this.screeSize.width;
        this.maskParam.w = pos.y / this.screeSize.height;
        this.mat.setProperty(this.maskParamName, this.maskParam);
    }
    // 点击
    onTouchStart(e: EventTouch) {
        if (!this.isAnimFinished) return;

        const pos = e.getUILocation();
        pos.x -= this.screeSize.width * 0.5;
        pos.y -= this.screeSize.height * 0.5;

        pos.subtract2f(this.curPos.x, this.curPos.y);
        if (pos.length() < this.curRadius) {
            const clickCb = this.clickCb;
            this.clickCb = null;
            clickCb && clickCb();
        }
    }

    onShowCircleMask(d: { pos: Vec3, clickCb: Function, useAnim?: boolean, is3D?: boolean }) {
        this.block.enabled = true;
        this.tarOpacityRate = 1;
        const pos2d = v3(d.pos);
        // 3d坐标 -> 屏幕坐标
        if (d.is3D) {
            const camera = GlobalData.get(GlobalEnum.GlobalDataType.Camera3D) as Camera;
            camera.convertToUINode(d.pos, this.node, pos2d);
        }
        this.tarPos.set(pos2d);
        this.isAnimFinished = false;
        if (!d.useAnim) {
            this.curPos.set(pos2d);
            this.isAnimFinished = true;
            this.setMaskParam(this.curPos);
        }

        this.clickCb = d.clickCb;
    }

    onHideCircleMask() {
        this.block.enabled = false;
        this.tarOpacityRate = 0;
        this.clickCb = null;
    }

}


const tmpP3_0 = v3();